import {
  env
} from './env.js'

let pendingRequest = new Map() 
const statusMap = new Map([
  [400, '参数错误'],
  [401, '需要身份认证'],
  [403, '拒绝访问'],
  [404, '请求错误,未找到该资源'],
  [405, '请求方法被禁止'],
  [406, '请求无法完成'],
  [407, '代理请求需要授权'],
  [408, '服务器等待客户端发送的请求时间过长'],
  [409, '服务器处理请求时发生了冲突'],
  [410, '请求资源被永久删除了'],
  [413, '请求数据太大'],
  [414, '请求url过长'],
  [415, '服务器无法处理请求附带的媒体格式'],
  [500, '服务器端出错！'],
  [501, '不支持的请求'],
  [502, '线路繁忙'],
  [503, '系统升级维护中'],
  [504, '请求超时！请尝试刷新页面重试'],
])
const serverText = '服务器出错啦'
function getReqKey(params) {
  let {
    url = '',
		method = '',
		data = {}
  } = params
  const requestKey = [
    url,
    method,
    JSON.stringify(data),
  ].join('&')
  return requestKey
}

function removeReqKey(key) {
  if (pendingRequest.has(key)) {
    const cancelToken = pendingRequest.get(key)
    cancelToken.abort()
    pendingRequest.delete(key)
  }
}

const errorTip = (title = '') => {
  wx.showToast({
    title,
    icon: 'none',
    duration: 2000
  })
}

function request(url, method = "POST", data = {}, options = {} , loading = false){
	const { key } = options
	return new Promise((resolve, reject) => {
		let requestKey = getReqKey({
			url,
			method,
			data,
		})
		if (pendingRequest.has(requestKey)) {
			removeReqKey(requestKey)
		}
		let requestTask
		requestTask = uni.request({
			url: env.BASE_URL + env.BASE_PARAMS + url,
			data,
			method: method,
			header: {
				'content-type': 'application/x-www-form-urlencoded;charset=utf-8',
				'token': uni.getStorageSync("token"),
				'key': key || uni.getStorageSync("key"),
			},
			success: (res) => {
				removeReqKey(requestKey)
				let status = res.statusCode
				if (status == 200) {
					let {
						code = 0
					} = res.data
					if ([-1, '-1', 2, '-2', -3, '-5',-5].includes(code)) { //token过期、无效之后去首页自动登录
						uni.clearStorage()
						uni.showModal({
							content:"哎呀，出了点意外情况，需要您重新登录!",
							showCancel:false,
							success(res){
								if (res.confirm){
									uni.redirectTo({
										url:"/pages/login/index"
									})
								}
							}
						})
						reject(res.data)
					} else {
						if (code != 0) {
							uni.showToast({
								title: res.data.msg || '服务器错误',
								icon: 'none',
							})
							return reject(res.data)
						}
						resolve(res.data)
					}
				} else {
					if (statusMap.get(status)) {
						statusMap.get(status) ? errorTip(`${statusMap.get(status)}`) : ''
					}
					reject(statusMap.get(status))
				}
			},
			fail: (err) => {
				console.log('err:',err)
				console.log('err:',err?.errMsg == "request:fail abort")
				if (err?.errMsg != "request:fail abort") {
					reject(err, serverText)
					errorTip(serverText)
				}
			},
			complete: (params) => {
				loading && uni.hideLoading()
			}
		})
		pendingRequest.set(requestKey, requestTask)
	})
}

function uploadFileOs(ossDt = {}) {
  let signature = ossDt.signature
  let ossAccessKeyId = ossDt.cre.accessKeyId
  let policy = ossDt.policy
  let key = ossDt.dir 
  let securityToken = ossDt.cre.securityToken
  console.log('ossDt:',ossDt)
  return new Promise((resolve, reject) => {
    uni.uploadFile({
      url: env.UPLOAD_URL,
      filePath: ossDt.filePath,
      name: 'file', // 必须填file。
      formData: {
        key,
        policy,
        OSSAccessKeyId: ossAccessKeyId,
        signature,
        'x-oss-security-token': securityToken // 使用STS签名时必传。
      },
      success: (res) => {
        if (res.statusCode === 204) {
          console.log('上传成功')
          resolve({
            code: 1,
            file: ossDt.filePath
          })
        } else {
          console.log('上传失败非204:',res)
          errorTip('上传Error')
          log.error('上传失败非204'+ ':' + res.data + '上传参数：' + JSON.stringify(ossDt))
          reject({ code: 0})
        }
      },
      fail: err => {
        console.log('上传失败：',err)
        log.error('上传失败oss：'+ ':' + JSON.stringify(err) + '上传参数：' + JSON.stringify(ossDt))
        errorTip('上传失败'+err)
        reject(err)
      }
    })
  })
}

class MiniFetch{
	post(url, data = {}, options = {}, loading = false) {
	  return request(url, 'POST', data, options, loading)
	}	
}

const minifetch = new MiniFetch()

export {
	minifetch,
	uploadFileOs
}